
package cn.cmcc.online.smsapi.sdk.db.entity.pubinfo;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import cn.cmcc.online.smsapi.sdk.constant.Constant;
import cn.cmcc.online.smsapi.sdk.db.DBManager;
import cn.cmcc.online.smsapi.sdk.db.XyCursor;
import cn.cmcc.online.smsapi.sdk.db.base.BaseManager;
import cn.cmcc.online.smsapi.sdk.db.entity.SmsParseRecorder;
import cn.cmcc.online.smsapi.sdk.dex.DexUtil;
import cn.cmcc.online.smsapi.sdk.log.LogManager;
import cn.cmcc.online.smsapi.sdk.net.util.Signaturer;
import cn.cmcc.online.smsapi.sdk.util.StringUtils;

/* SDK-421 huangzhiqiang 20160525 start */
public class ShardDataManager {

    public static final String ID = "id"; // 自增ID
    public static final String NUM = "num"; // 公众号
    public static final String ENCODE_CONTENT = "encode_content"; // 加密后的去敏短信内容
    public static final String CONTENT_SIGN = "content_sign"; // 去敏短信内容SHA256签名
    public static final String STATUS = "status"; // 请求状态（0:未请求 1:已请求）
    public static final String MSG_TIME = "msg_time"; // 短信接收时间

    private static final String TABLE_NAME = "tb_shard_data";
    public static final String DROP_TABLE = " DROP TABLE IF EXISTS " + TABLE_NAME;

    public static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" + ID
            + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " + NUM + " TEXT NOT NULL, " + ENCODE_CONTENT
            + " TEXT NOT NULL, " + CONTENT_SIGN + " TEXT NOT NULL, " + STATUS + " INTEGER DEFAULT 0, " + MSG_TIME
            + " INTEGER DEFAULT 0)";

    /**
     * 请求状态
     * 
     */
    public enum RequestStatus {
        /**
         * 未请求
         */
        STATUS_NOT_REQUEST,
        /**
         * 已请求
         */
        STATUS_HAS_REQUEST,
        /**
         * 全部状态
         */
        ALL;

        @Override
        public String toString() {
            switch (this) {
            case STATUS_NOT_REQUEST:
                return "0";
            case STATUS_HAS_REQUEST:
                return "1";
            case ALL:
                return "2";
            default:
                return "UNKNOWN";
            }
        }
    }

    /**
     * 解析分片相关数据
     * 
     * @param paramsMap
     */
    public static void parseShardSignForMsg(Map<String, String> paramsMap) {
        if (paramsMap == null || paramsMap.isEmpty()) {
            return;
        }
        try {
            String num = StringUtils.getPhoneNumberNo86(paramsMap.get("num"));
            String msg = paramsMap.get("msg");
            String strSmsTime = paramsMap.get("smsTime");
            if (StringUtils.isNull(num) || StringUtils.isNull(msg) || StringUtils.isNull(strSmsTime)) {
                return;
            }

            msg = msg.trim();
            // 去敏后的短信内容，替换了关键字信息
            String replaceKeywordMsg = DexUtil.multiReplace(msg);
            if (StringUtils.isNull(replaceKeywordMsg)) {
                return;
            }

            // 加密后的去敏短信内容
            String encodeReplaceKeywordMsg = StringUtils.encode(replaceKeywordMsg);
            if (StringUtils.isNull(encodeReplaceKeywordMsg)) {
                return;
            }

            // 去敏短信内容SHA256签名
            String contentSign = Signaturer.sha256Encode(replaceKeywordMsg);
            // 数据入库
            insert(num, encodeReplaceKeywordMsg, contentSign, strSmsTime);
        } catch (Throwable e) {
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG, "ShardDataManager parseShardSignForMsg error:", e);
            /*SDK-550 hewengao 20160719 end*/
        }
    }

    /**
     * 插入数据
     * 
     * @param num 公众号
     * @param encodeContent 加密后的去敏短信内容
     * @param contentSign 去敏短信内容SHA256签名
     * @param msgTime 短信接收时间(字符串long型数据)
     * @return
     */
    public static long insert(String num, String encodeContent, String contentSign, String msgTime) {
        if (StringUtils.isNull(num) || StringUtils.isNull(encodeContent) || StringUtils.isNull(contentSign)) {
            return -1;
        }
        XyCursor xyCursor = null;
        try {
            xyCursor = DBManager.query(TABLE_NAME, new String[] { num }, NUM + "=? AND " + ENCODE_CONTENT + "=? ",
                    new String[] { num, encodeContent });

            // 已存在相同数据则不再新增
            if (xyCursor != null && xyCursor.getCount() > 0) {
                return 0;
            }
            return DBManager.insert(TABLE_NAME, BaseManager.getContentValues(null, NUM, num, ENCODE_CONTENT,
                    encodeContent, CONTENT_SIGN, contentSign, MSG_TIME, msgTime));
        } catch (Throwable e) {
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG, "ShardDataManager insert error:", e);
            /*SDK-550 hewengao 20160719 end*/
        } finally {
            XyCursor.closeCursor(xyCursor, true);
        }
        return -1;
    }

    /**
     * 根据去敏短信内容SHA256签名更新请求状态
     * 
     * @param contentSign 去敏短信内容SHA256签名
     * @param status 请求状态（0:未请求 1:已请求）
     * @return
     */
    public static long updateStatusByContentSign(String contentSign, RequestStatus status) {
        try {
            return DBManager.update(TABLE_NAME, BaseManager.getContentValues(null, STATUS, status.toString()),
                    CONTENT_SIGN + "=? ", new String[] { contentSign });
        } catch (Throwable e) {
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG, "ShardDataManager  error:" , e);
            /*SDK-550 hewengao 20160719 end*/
        }
        return -1;
    }

    /**
     * 根据去敏短信内容SHA256签名更新请求状态
     * 
     * @param contentSigns 去敏短信内容SHA256签名集合
     * @param status 请求状态（0:未请求 1:已请求）
     * @return
     */
    public static long updateStatusByContentSign(List<String> contentSigns, RequestStatus status) {
        try {
            int size = contentSigns.size();
            String placeholders = SmsParseRecorder.makePlaceholders(size);
            String whereClause = CONTENT_SIGN + " IN(" + placeholders + ")";
            String[] whereArgs = contentSigns.toArray(new String[size]);
            return DBManager.update(TABLE_NAME, BaseManager.getContentValues(null, STATUS, status.toString()),
                    whereClause, whereArgs);
        } catch (Throwable e) {
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG, "ShardDataManager error:", e);
            /*SDK-550 hewengao 20160719 start*/
        }
        return -1;
    }

    /**
     * 根据去敏原文sha256签名获取数据
     * 
     * @param contentSign
     * @return
     */
    public static ShardData queryShardDataByContentSign(String contentSign) {
        List<ShardData> shardDataList = query(CONTENT_SIGN + "=? ", new String[] { contentSign }, 1);
        return (shardDataList == null || shardDataList.size() < 1) ? null : shardDataList.get(0);
    }

    /**
     * 根据号码获取指定数量的分片数据
     * 
     * @param num 号码
     * @param status 请求状态（0:未请求 1:已请求 2:全部）
     * @param limit 获取的最大数据数量
     * @return
     */
    public static List<ShardData> queryShardDataByNum(String num, RequestStatus status, int limit) {
        if (status != RequestStatus.ALL) {
            return query(NUM + "=? AND " + STATUS + "=? ", new String[] { num, status.toString() }, limit);
        }
        return query(NUM + "=? ", new String[] { num }, limit);
    }

    /**
     * 根据查询条件获取数据
     * 
     * @param whereClause
     * @param whereArgs
     * @param limit
     * @return
     */
    public static List<ShardData> query(String whereClause, String[] whereArgs, int limit) {
        XyCursor xyCursor = null;
        try {
            xyCursor = DBManager.query(false, TABLE_NAME,
                    new String[] { ID, NUM, ENCODE_CONTENT, CONTENT_SIGN, STATUS, MSG_TIME }, whereClause, whereArgs,
                    null, null, null, String.valueOf(limit));

            if (xyCursor == null || xyCursor.getCount() == 0) {
                return null;
            }
            List<ShardData> shardDataList = new ArrayList<ShardData>();
            ShardData shardData = null;
            while (xyCursor.moveToNext()) {
                shardData = new ShardData();
                shardData.id = xyCursor.getInt(xyCursor.getColumnIndex(ID));
                shardData.num = xyCursor.getString(xyCursor.getColumnIndex(NUM));
                shardData.encodeContent = xyCursor.getString(xyCursor.getColumnIndex(ENCODE_CONTENT));
                shardData.contentSign = xyCursor.getString(xyCursor.getColumnIndex(CONTENT_SIGN));
                shardData.status = xyCursor.getInt(xyCursor.getColumnIndex(STATUS));
                shardData.msgTime = xyCursor.getLong(xyCursor.getColumnIndex(MSG_TIME));
                shardDataList.add(shardData);
            }
            return shardDataList;
        } catch (Throwable e) {
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG, "ShardDataManager query error:", e);
            /*SDK-550 hewengao 20160719 end*/
        } finally {
            XyCursor.closeCursor(xyCursor, true);
        }
        return null;
    }

    /**
     * 删除指定时间之前的数据
     * 
     * @param lastTime 删除该时间之前的数据
     */
    public static void deleteBeforeLastTime(long lastTime) {
        try {
            DBManager.delete(TABLE_NAME, MSG_TIME + "<=?", new String[] { String.valueOf(lastTime) });
        } catch (Throwable e) {
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG,"ShardDataManager deleteBeforeLastTime", e);
            /*SDK-550 hewengao 20160719 end*/
        }
    }
}
/* SDK-421 huangzhiqiang 20160525 end */
